package cn.bisoft.java.service.ext.httpclient.core;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

public abstract class BaseHttpService implements HttpService {
	
	private static final Log logger = LogFactory.getLog(BaseHttpService.class);
	
	private static final int MAX_LENGTH = 4096;

	protected HttpClient client;
	
	protected HttpRequestBase httpMethod;
	
	private String server;
	
	private String uri;

	private String method;
	
	private String getParams;
	
	private UrlEncodedFormEntity postParams;
	
	@Override
	public void sendRequest() {
		
		createHttpClient();
		
		createHttpMethod();
		
		execute();
		
		destroy();
	}
	
	protected void createHttpClient()
	{
		if (null == client)
		{
			client = new DefaultHttpClient();
		}
		
	}
	
	protected void createHttpMethod()
	{
		if ("POST".equalsIgnoreCase(method))
		{
			String url = this.server + this.uri;
			httpMethod = new HttpPost(url);
			((HttpPost)httpMethod).setEntity(this.postParams);
		}
		else
		{
			String url = this.server + this.uri + this.getParams;
			httpMethod = new HttpGet(url);
		}
	}
	
	abstract protected void execute();
	
	protected void destroy()
	{
		if (null != httpMethod)
		{
			httpMethod.abort();
		}
	}
	
	public void setPostParams(Map<String, String> paramsMap, String encode)
	{
		UrlEncodedFormEntity postParams = null;
		List<NameValuePair> formParams = new ArrayList<NameValuePair>();
		
		if (null != paramsMap && paramsMap.size() > 0)
		{
			for (Entry<String, String> e : paramsMap.entrySet())
			{
				formParams.add(new BasicNameValuePair(e.getKey(), e.getValue()));
			}

			try
			{
				postParams = new UrlEncodedFormEntity(formParams, encode);
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
		
		this.method = "POST";
		this.postParams = postParams;
	}
	
	public void setGetParams(Map<String, String> paramsMap)
	{
		String getParams = "";
		
		if (null != paramsMap && paramsMap.size() > 0)
		{
			getParams += "?";
			
			for (Entry<String, String> e : paramsMap.entrySet())
			{
				getParams += e.getKey() + "=" + e.getValue() + "&";
			}
			
			getParams = getParams.substring(0, getParams.length() - 1);
		}
		
		if (getParams.length() > MAX_LENGTH)
		{
			logger.error("length is too large: " + getParams);
		}
		
		this.method = "GET";
		this.getParams = getParams;
	}

	public String getServer()
	{
		return server;
	}

	public void setServer(String server)
	{
		this.server = server;
	}

	public String getUri()
	{
		return uri;
	}

	public void setUri(String uri)
	{
		this.uri = uri;
	}

	public String getMethod()
	{
		return method;
	}
}
